package localserver;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

import common.Player;
import common.PlayerService;

public class PlayerServiceImpl extends UnicastRemoteObject implements
		PlayerService {

	private String serverGeolocation;

	protected PlayerServiceImpl(String serverGeolocation)
			throws RemoteException {
		super();
		this.serverGeolocation = serverGeolocation;
	}

	public void createPlayerAccount(String firstName, String lastName, int age,
			String userName, String password, String iPAddress)
			throws RemoteException {

		Player playerNew = new Player(firstName, lastName, age, userName,
				password, iPAddress);

		if (!common.Tools.isLegalIpAddress(iPAddress, serverGeolocation)) {

			common.Tools.writeLog("server", serverGeolocation,
					"Wrong IP Address:" + playerNew, true);
			System.out.println("Wrong IP Address");
			throw new RemoteException("server" + serverGeolocation
					+ " Wrong IP Address:" + playerNew);
		}

		List<Player> list = getList(userName);
		String key = userName.substring(0, 1).toUpperCase();
		PlayerHashTable hashTable = PlayerHashTable.getInstance();
		ArrayList semaphores = PlayerHashTable.getListsemaphores();
		int keyIndex = semaphores.indexOf(key);
		keyIndex = (keyIndex < 0) ? 0 : keyIndex;
		synchronized (semaphores.get(keyIndex)) {
			if (list == null) {
				list = new ArrayList<Player>();
				hashTable.put(key, list);
			}
			for (int i = 0; i < list.size(); i++) {
				Player p = list.get(i);
				if (p.getUserName().equals(playerNew.getUserName())) {

					common.Tools.writeLog("server", serverGeolocation,
							"Account is already created:" + playerNew, true);
					System.out.println("Account is already created:"
							+ playerNew);
					throw new RemoteException("server" + serverGeolocation
							+ " Account is already created:" + playerNew);
				}
			}

			list.add(playerNew);
		}
		common.Tools.writeLog("server", serverGeolocation, "Account created: "
				+ playerNew, true);

		common.Tools.writeLog(userName, serverGeolocation, "Account created "
				+ playerNew, true);

		System.out.println("We did create the the account: " + userName);
	}

	public void playerSignIn(String userName, String password, String iPAddress)
			throws RemoteException {

		Player playerNew = new Player(" ", " ", 0, userName, password,
				iPAddress);
		if (!common.Tools.isLegalIpAddress(iPAddress, serverGeolocation)) {
			throw new RemoteException("server" + serverGeolocation
					+ " Wrong IP Address:" + playerNew);
		}
		boolean userExist = false;
		List<Player> list = getList(userName);
		if (list == null) {
			common.Tools.writeLog("server", serverGeolocation,
					"User Does not exit: " + playerNew, true);
			common.Tools.writeLog(userName, serverGeolocation,
					"User Does not exit: " + playerNew, true);

			throw new RemoteException("server" + serverGeolocation
					+ " User Does not exit: " + playerNew);
		}
		synchronized (list) {
			for (int i = 0; i < list.size(); i++) {
				Player p = list.get(i);
				if (p.getUserName().equals(userName)
						&& p.getPassword().equals(password)
						&& p.getIPAddress().equals(iPAddress)) {
					userExist = true;
					if (!p.isOnline()) {
						p.setOnline(true);

						System.out.println("player Signed in");
						common.Tools.writeLog("server", serverGeolocation,
								"User Signed in: " + playerNew, true);
						common.Tools.writeLog(userName, serverGeolocation,
								"User Signed in: " + playerNew, true);

					} else {
						System.out.println("User is already online");
						common.Tools.writeLog("server", serverGeolocation,
								"User is already online: " + playerNew, true);
						common.Tools.writeLog(userName, serverGeolocation,
								"User is already online: " + playerNew, true);

						throw new RemoteException("server" + serverGeolocation
								+ " User is already online: " + playerNew);
					}

					return;
				}
			}
		}
		if (!userExist) {
			System.out.println(" User Does not exit");
			common.Tools.writeLog("server", serverGeolocation,
					"User Does not exit userName: " + playerNew, true);
			common.Tools.writeLog(userName, serverGeolocation,
					"User Does not exit userName: " + playerNew, true);
			throw new RemoteException("server" + serverGeolocation
					+ " User Does not exit:  " + playerNew);
		}

	}

	public void playerSignOut(String userName, String iPAddress)
			throws RemoteException {

		Player playerNew = new Player(" ", " ", 0, userName, " ", iPAddress);
		if (!common.Tools.isLegalIpAddress(iPAddress, serverGeolocation)) {
			common.Tools.writeLog("server", serverGeolocation,
					"Wrong IP Address:" + playerNew, true);
			System.out.println("Wrong IP Address");
			throw new RemoteException("server" + serverGeolocation
					+ " Wrong IP Address:" + playerNew);
		}
		boolean userExist = false;
		List<Player> list = getList(userName);
		if (list == null) {
			common.Tools.writeLog("server", serverGeolocation,
					"User Does not exit: " + playerNew, true);
			common.Tools.writeLog(userName, serverGeolocation,
					"User Does not exit: " + playerNew, true);
			throw new RemoteException("server" + serverGeolocation
					+ " User Does not exit:" + playerNew);
		}
		synchronized (list) {
			for (int i = 0; i < list.size(); i++) {
				Player p = list.get(i);
				if (p.getUserName().equals(userName)
						&& p.getIPAddress().equals(iPAddress)
				/* &&p.isOnline()==true */
				) {
					userExist = true;
					if (p.isOnline()) {
						p.setOnline(false);
						System.out.println("User Signed out");
						common.Tools.writeLog("server", serverGeolocation,
								"Player Signed out: " + playerNew, true);
						common.Tools.writeLog(userName, serverGeolocation,
								"Player Signed out: " + playerNew, true);

					} else {
						System.out.println("User is not online");
						common.Tools.writeLog("server", serverGeolocation,
								"User is not online: " + playerNew, true);
						common.Tools.writeLog(userName, serverGeolocation,
								"User is not online: " + playerNew, true);

					}

					return;
				}
			}
		}
		if (!userExist) {
			System.out.println("User Does not exit");
			common.Tools.writeLog("server", serverGeolocation,
					"User Does not exit: " + playerNew, true);
			common.Tools.writeLog(userName, serverGeolocation,
					"User Does not exit: " + playerNew, true);

		}

	}

	private List getList(String userName) {
		String key = userName.substring(0, 1).toUpperCase();
		PlayerHashTable hashTable = PlayerHashTable.getInstance();
		List<Player> list = (List<Player>) hashTable.get(key);
		return list;
	}
}